/*******************************************************************************
 * Copyright (c) 2011 squid.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     squid - initial API and implementation
 ******************************************************************************/
package com.google.code.cubeirc.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;

import lombok.Getter;
import lombok.Setter;

import org.apache.log4j.Level;

import com.google.code.cubeirc.common.ApplicationInfo;
import com.google.code.cubeirc.debug.DebuggerQueue;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider;
import com.thoughtworks.xstream.io.xml.DomDriver;

public final class Configuration {
	@Setter @Getter
	public static UserSettings currentUSConfig;

	@Getter @Setter
	public static ArrayList<ConnectionSettings> currentCSSettings;

	@Getter @Setter
	public static ArrayList<ColorSettings> currentColorsSettings;

	@Getter @Setter
	public static Boolean Loaded;

	public static Boolean CheckConfiguration(String filename)
	{		
		Random rnd = new Random();

		File cFile = new File(ApplicationInfo.CFG_DEFAULT_DIRECTORY);
		if (!cFile.exists())
			cFile.mkdir();

		addDebug(Level.INFO, "Checking config file %s", filename);

		File f = new File(filename);
		if (!f.exists())
		{
			addDebug(Level.INFO, "Saving default config");
			ArrayList<EditorSettings> es = new ArrayList<EditorSettings>();
			es.add(new EditorSettings(ApplicationInfo.EDT_DEFAULT_NAME, ApplicationInfo.EDT_DEFAULT_FONTNAME, ApplicationInfo.EDT_DEFAULT_FONTSIZE,  ApplicationInfo.EDT_DEFAULT_BACKGROUND.getRGB().toString(), ApplicationInfo.EDT_DEFAULT_FOREGROUND.getRGB().toString()));			
			UserSettings us = new UserSettings("CubeIRCUser" + rnd.nextInt(1000), "CubeIRCUser" + rnd.nextInt(1000), "Please edit this settings", "please@editthissettings.it",es);						
			saveUStoFile(filename, us);
			setLoaded(true);
			return false;
		}		
		else
			return true;
	}

	public static void addEditorSettings(EditorSettings ed)
	{
		EditorSettings torm = null;
		addDebug(Level.DEBUG, "Adding Editorsetting %s to config",ed.getName());
		ArrayList<EditorSettings> l_ed = getCurrentUSConfig().getEditorsettings();
		for (Iterator<EditorSettings> it = l_ed.iterator(); it.hasNext();)
		{
			EditorSettings item = it.next();
			if (item.getName().equals(ed.getName()))
				torm = item;
		}

		if (torm != null)
			l_ed.remove(torm);

		l_ed.add(ed);
		currentUSConfig.setEditorsettings(l_ed);

		saveUStoFile(ApplicationInfo.CFG_SETTINGS, getCurrentUSConfig());
		loadUSfromFile(ApplicationInfo.CFG_SETTINGS);
	}
	public static EditorSettings getEditorSettings(String editor)
	{
		EditorSettings res = null;
		if (getCurrentUSConfig() != null)
		{
			ArrayList<EditorSettings> editors = getCurrentUSConfig().getEditorsettings();
			for (int i=0; i< editors.size();i++)
			{
				if (editors.get(i).getName().equals(editor))
					res =  editors.get(i);
			}

		}
		else
		{
			if (!getLoaded())
			{
				CheckConfiguration(ApplicationInfo.CFG_SETTINGS);
				return getEditorSettings(editor);
			}
		}


		return res;
	}

	public static ArrayList<ConnectionSettings> loadCSfromFile(String filename)
	{
		try
		{
			XStream xstream = new XStream(new Sun14ReflectionProvider( ), new DomDriver( ));
			@SuppressWarnings("unchecked")
			ArrayList<ConnectionSettings> fromXML = (ArrayList<ConnectionSettings>)xstream.fromXML(new FileInputStream(filename));
			setCurrentCSSettings(fromXML);
			return fromXML;
		}
		catch(Exception ex)
		{
			DebuggerQueue.addDebug(Configuration.class,Level.FATAL, "Error during load file %s: %s",filename, ex.getMessage());
			return null;
		}
	}

	public static void saveCStoFile(String filename, ArrayList<ConnectionSettings> cs )
	{
		try {
			XStream xstream = new XStream(new Sun14ReflectionProvider( ), new DomDriver( ));
			xstream.toXML(cs,new FileOutputStream(filename));
		} catch (FileNotFoundException e) {
			DebuggerQueue.addDebug(Configuration.class,Level.FATAL, "Error during save file %s: %s",filename, e.getMessage());
		}
	}


	public static void saveUStoFile(String filename, UserSettings us)
	{
		try {
			addDebug(Level.INFO, "Saving config %s",filename);
			XStream xstream = new XStream(new Sun14ReflectionProvider( ), new DomDriver( ));
			xstream.toXML(us,new FileOutputStream(filename));
		} catch (FileNotFoundException e) {
			DebuggerQueue.addDebug(Configuration.class,Level.FATAL, "Error during save file %s: %s",filename, e.getMessage());
		}	
	}

	public static UserSettings loadUSfromFile(String filename)
	{
		try
		{
			XStream xstream = new XStream(new Sun14ReflectionProvider( ), new DomDriver( ));
			UserSettings fromXML = (UserSettings)xstream.fromXML(new FileInputStream(filename));
			setCurrentUSConfig(fromXML);
			return fromXML;
		}
		catch(Exception ex)
		{
			DebuggerQueue.addDebug(Configuration.class,Level.FATAL, "Error during load file %s: %s",filename, ex.getMessage());
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	public static ArrayList<ColorSettings> loadColorsSettings(String filename)
	{
		try
		{
			XStream xstream = new XStream(new Sun14ReflectionProvider( ), new DomDriver( ));
			ArrayList<ColorSettings> fromXML = ( ArrayList<ColorSettings>)xstream.fromXML(new FileInputStream(filename));
			setCurrentColorsSettings(fromXML);
			return fromXML;
		}
		catch(Exception ex)
		{
			DebuggerQueue.addDebug(Configuration.class,Level.FATAL, "Error during load file %s: %s",filename, ex.getMessage());
			return null;
		}		
	}

	public static void saveColorsSettings(String filename, ArrayList<ColorSettings> cs)
	{
		try {
			addDebug(Level.INFO, "Saving config %s",filename);
			XStream xstream = new XStream(new Sun14ReflectionProvider( ), new DomDriver( ));
			xstream.toXML(cs,new FileOutputStream(filename));
		} catch (FileNotFoundException e) {
			DebuggerQueue.addDebug(Configuration.class,Level.FATAL, "Error during save file %s: %s",filename, e.getMessage());
		}	

	}

	public static String getColorSetting(String name)
	{
		String prefix = "";
		String ret = "";
		if (currentColorsSettings != null)
		{
			for (Iterator<ColorSettings> it = currentColorsSettings.iterator(); it.hasNext();)
			{
				ColorSettings cs = it.next();
				if (cs.getName().equals(name))
				{
					ret += "\u0003";

					if (cs.getBackground() != -1)
					{
						prefix = ",";
						if (cs.getBackground()> 9)
							ret += Integer.toString(cs.getBackground());
						else
							ret += "0"+Integer.toString(cs.getBackground());
					}
					if (cs.getForeground() != -1)
					{
						
						ret += prefix+Integer.toString(cs.getForeground());						
					}
				}
			}
		}

		return ret;
	}

	public static void CheckColorsSettings()
	{
		File f = new File(ApplicationInfo.CLS_COLORS);

		if (!f.exists())
		{
			setCurrentColorsSettings(new ArrayList<ColorSettings>());
			getCurrentColorsSettings().add(new ColorSettings(ApplicationInfo.CLS_COLOR_NOTICE, -1, -1));
			getCurrentColorsSettings().add(new ColorSettings(ApplicationInfo.CLS_COLOR_GLOBAL, -1, -1));
			getCurrentColorsSettings().add(new ColorSettings(ApplicationInfo.CLS_COLOR_USERMSG, -1, -1));

			saveColorsSettings(ApplicationInfo.CLS_COLORS,getCurrentColorsSettings());


		}
		loadColorsSettings(ApplicationInfo.CLS_COLORS);
	}



	private static void addDebug(Level level, String text, Object ... args)
	{
		DebuggerQueue.addDebug(Configuration.class, level, text, args);
	}

}
